package cn.comon.app.scan.analysis;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Properties;
import net.sf.json.JSONObject;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.comon.app.scan.entity.AsReportinfo;
import cn.comon.app.scan.service.AsReportinfoService;
import cn.comon.app.scan.util.SpringContextUtil;
import cn.comon.app.scan.util.UtilTools;
@Service
public class IAnalysisImpl implements IAnalysis{
//    @Autowired
//    IAnalysisMSG tencentAnalysis;
//    @Autowired
//    IAnalysisMSG netQinAnalysis;
//    @Autowired
//    IAnalysisMSG dubaAnalysis;
//    @Autowired
//    IAnalysisMSG aQGJAnalysis;
    @Autowired
    private AsReportinfoService asReportinfoService;
    
    public static boolean isExcuting = false;
    
    // http连接缓存,只缓存当前任务
//    private Map<String, HttpURLConnection> connectMaps = new HashMap<String, HttpURLConnection>();
    
    static Logger logger = Logger.getLogger(IAnalysisImpl.class.getName());
    
    public boolean sendRequest(Properties params, List<AsReportinfo> appDataList) {
    	
    	// 如果上一次任务正在执行，则放弃本次任务
    	if (isExcuting()) {
    		logger.warn("上一次任务正在执行，放弃本次任务");
    		return false;
    	} else {
        	// 正在执行
        	setExcuting(true);	
    	}
    	// 发送数据
    	for (AsReportinfo asReportinfo:appDataList) {
    		// 向腾讯发送数据
    	    this.process(params, asReportinfo, "tencentAnalysis");
    		// 向网秦发送数据
    	    this.process(params, asReportinfo, "netQinAnalysis");
    		// 向安全管家发送数据
    	    this.process(params, asReportinfo, "aQGJAnalysis");
    		// 向金山发送数据
    	    this.process(params, asReportinfo, "dubaAnalysis");
    		
    	}
    	// 关闭连接（建议每次发送新建连接）
//    	closeHttpURLConnection("QQ");
//    	closeHttpURLConnection("aqgj");
//    	closeHttpURLConnection("duba");
//    	closeHttpURLConnection("netqin");
    	
    	// 执行完毕
    	setExcuting(false);
    	return true;
    }
    /**
     * 获取连接
     * @param url
     * @return
     */
    private HttpURLConnection getHttpURLConnection(String url, String type) {
    	HttpURLConnection connection = null;
    	try {
    		//有可能占用端口，建议每次请求新建连接
//    		if(connectMaps.containsKey(type)) {
//    			connection = connectMaps.get(type);
//    			// 这个连接有可能超时或许已经断开，需判断,具体方法或代码上网查查
//    			if(true) {
//    				return connection;
//    			}
//    			
//    		}
    		
    		URL request = new URL(url);
    		connection = (HttpURLConnection)request.openConnection();

            //构造post请求
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setRequestMethod("POST");
            connection.setUseCaches(false);
            connection.setInstanceFollowRedirects(true);
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

            //设置连接主机超时（单位：毫秒）。1000 毫秒= 1秒
            connection.setConnectTimeout(30000);
            //设置从主机读取数据超时（单位：毫秒）
            connection.setReadTimeout(30000);
            
            // 缓存连接
//            connectMaps.put(type, connection);
            return connection;
    	} catch (Exception e) {
    		e.printStackTrace();
    		return null;
    	}
    }
    
    private void closeHttpURLConnection(HttpURLConnection connection) {
    	try {
    		connection.disconnect();
    	} catch (Exception e) {
    		e.printStackTrace();
    	}
    }
    
    
    private void process(Properties params, AsReportinfo asReportinfo, String type) {
    	HttpURLConnection connection = null;
    	JSONObject sendData = null;
    	JSONObject resultJson = null;
    	try {
			// 获取接口数据
    		IAnalysisMSG iAnalysisMSG = (IAnalysisMSG)SpringContextUtil.getBean(type);
    		sendData = (JSONObject)iAnalysisMSG.getSendData(params, asReportinfo);
    		
    		// 获取连接
    		connection = this.getHttpURLConnection(sendData.getString("sendUrl"), type);
    		// 发送数据
    		resultJson = (JSONObject)this.send(connection, sendData.getString("postData"));
            // 更新发送结果
            updateScanStatus(asReportinfo, resultJson);
            // 关闭连接
            closeHttpURLConnection(connection);
		} catch(Exception e) {
			e.printStackTrace();
		}
    }
    
    private static synchronized boolean isExcuting() {
		return isExcuting;
	}

    private static synchronized void setExcuting(boolean isExcuting) {
		IAnalysisImpl.isExcuting = isExcuting;
	}

    private Object send(HttpURLConnection connection, String postData) {
		try {
			//获取需要检测的软件信息。
	        DataOutputStream writeStream = new DataOutputStream(connection.getOutputStream());
	        writeStream.writeBytes(postData); 
	        writeStream.flush();
	        writeStream.close();
				
	        BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
	        String line="";
	        String result = "";
	        logger.info("<----------------response from Tencent Start---------------->");
	        while ((line = reader.readLine()) != null){
	           //eg:{"result":"error", "reason":"invalid ip"}
	        	result = result + line;
	        }
	        JSONObject resultJson = JSONObject.fromObject(result);
	        logger.info("response's message from Tencent:" + result);
	        logger.info("JSON message result:" + resultJson.getString("result"));
	        logger.info("JSON message reason:" + resultJson.getString("reason"));
	        logger.info("<----------------response from Tencent End---------------->");
	        
	        return resultJson;
		} catch(Exception e) {
			e.printStackTrace();
			return null;
		}
		
    }
    /**
     * 更新状态
     * @param asReportinfo
     * @param resultJson
     */
    private void updateScanStatus(AsReportinfo asReportinfo, JSONObject resultJson) {
		
        // 主机响应正常，举报信息正常发送完毕。DB状态更新。
        //记录的过期时间更新。（不管发送失败或是正常，该条记录的过期都要延后）
//        AsReportinfo asReportinfo = new AsReportinfo();
//        asReportinfo.setId(String.valueOf(asReportinfo.getId()));
//        scan.setAuthkey(resultJson.getString("result"));
//        scan.setAuthkey(resultJson.getString("reason"));
        //没更新一次，过期时间往后延长10天。
        asReportinfo.setExpired(UtilTools.getTimestamp(10));
        asReportinfoService.updateReportinfo(asReportinfo);
	}
}
